package com.gzmu.face.tools;

import java.io.*;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.HttpsURLConnection;
import static com.sun.org.apache.xml.internal.serialize.OutputFormat.Defaults.Encoding;

public class HttpUtil {
	// User-Agent
	public static final String USERAGENT_FIREFOX = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0";  
	public static final String USERAGENT_IE = "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko";  
	private static BasicCookieStore cookieStore;

    public static int httpsRequest(String requestUrl, String requestMethod, String output) throws IOException {
        URL url = new URL(null, requestUrl, new sun.net.www.protocol.https.Handler());
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setUseCaches(false);
        connection.setRequestMethod(requestMethod);
        int reslut = -1;
        if (null != output) {
            OutputStream outputStream = connection.getOutputStream();
            outputStream.write(output.getBytes("UTF-8"));
            outputStream.close();
			reslut = 0;
        }
        // 从输入流读取返回内容
        connection.disconnect();
        return reslut;
    }

	
	public static HttpResult doGet(String url, Map<String, String> headers, Map<String, String> params)
			throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, ClientProtocolException, IOException {
		if (url == null|| url.equals("")) {
			return null;
		}

		SSLContextBuilder builder = new SSLContextBuilder();
		builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
		cookieStore = new BasicCookieStore();
		CloseableHttpClient httpclient = HttpClients.custom().setDefaultCookieStore(cookieStore)
				.setSSLSocketFactory(sslsf).build();

		HttpResult result = null;
		try {
			url = url + "?" + parseParams(params);
			HttpGet httpget = new HttpGet(url);
			httpget.setHeaders(parseHeader(headers));
			CloseableHttpResponse response = httpclient.execute(httpget);
			try {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					result = new HttpResult();
					result.setCookies(cookieStore.getCookies());
					result.setStatusCode(response.getStatusLine().getStatusCode());
					result.setHeaders(response.getAllHeaders());
					result.setBody(EntityUtils.toString(entity));
				}
			} finally {
				response.close();
			}
		} finally {
			httpclient.close();
		}
		return result;
	}

	public static HttpResult doPost(String url, Map<String, String> headers, String postData)
			throws Exception {
//		if (url == null || url.equals("")) {
//			return null;
//		}
//		int socketTimeout = 10000;//读取数据超时
//		int connectTimeout = 10000;//链接超时
//		SocketConfig socketConfig = SocketConfig.custom()
//				.setSoKeepAlive(false)
//				.setSoLinger(1)
//				.setSoReuseAddress(true)
//				.setSoTimeout(connectTimeout)
//				.setTcpNoDelay(true).build();
//		RequestConfig config = RequestConfig.custom().setConnectTimeout(connectTimeout)
//				.setSocketTimeout(socketTimeout)
//				.setConnectionRequestTimeout(connectTimeout).build();
//		CloseableHttpClient httpClient = HttpClientBuilder.create()
//				.setDefaultSocketConfig(socketConfig)
//				.setDefaultRequestConfig(config).build();
//		HttpPost post = new HttpPost(url);
//		String tokenByte = Base64.encodeBase64String((headers.get( "name" )+":"+headers.get( "passwd" )).getBytes());
////		post.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
////				"(KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36");
//		post.setHeader("Authorization", "Basic "+ tokenByte);
//		post.setEntity(new StringEntity(postData, Encoding));
//		CloseableHttpResponse response = httpClient.execute(post);
		if (url == null || url.equals("")) {
			return null;
		}
		SSLContextBuilder builder = new SSLContextBuilder();
		builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
		cookieStore = new BasicCookieStore();
		CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore)
				.setSSLSocketFactory(sslsf).build();

		HttpPost post = new HttpPost(url);
		//请求超时
		post.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
		//读取超时
		post.getParams().setParameter( CoreConnectionPNames.SO_TIMEOUT,5000);
		String tokenByte = Base64.encodeBase64String((headers.get( "name" )+":"+headers.get( "passwd" )).getBytes());
		post.setHeader("Authorization", "Basic "+ tokenByte);

		post.setEntity(new StringEntity(postData, Encoding));

		CloseableHttpResponse response = httpClient.execute(post);
		HttpEntity entity = response.getEntity();
		HttpResult result = new HttpResult();
		result.setCookies(cookieStore.getCookies());
		result.setStatusCode(response.getStatusLine().getStatusCode());
		result.setHeaders(response.getAllHeaders());
		result.setBody(EntityUtils.toString(entity, Encoding));
		close(entity, response);
		return result;
	}

	private static String parseParams(Map<String, String> params) {
		if (params == null || params.isEmpty()) {
			return "";
		}

		StringBuffer sb = new StringBuffer();
		for (String key : params.keySet()) {
			sb.append(key + "=" + params.get(key) + "&");
		}
		return sb.substring(0, sb.length() - 1);

	}

	private static Header[] parseHeader(Map<String, String> headers) {
		if (headers == null || headers.isEmpty()) {
			return getDefaultHeaders();
		}
		Header[] retHeader = new BasicHeader[headers.size()];
		int i = 0;
		for (String str : headers.keySet()) {
			retHeader[i++] = new BasicHeader(str, headers.get(str));
		}
		return retHeader;
	}

	private static Header[] getDefaultHeaders() {
		Header[] headers = new BasicHeader[3];
		headers[0] = new BasicHeader("User-Agent", USERAGENT_IE);
		headers[1] = new BasicHeader("Accept-Encoding", "gzip, deflate");
		headers[2] = new BasicHeader("Accept-Language", "en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3");
		return headers;
	}

	private static void close(HttpEntity entity, CloseableHttpResponse response) {
		try {
			if (entity != null) {
				InputStream input = entity.getContent();
				input.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
			} catch (IOException e) {
			}
		}
	}
}
